package com.bitsemart;

import android.app.DialogFragment;
import android.app.SearchManager;
import android.content.Context;
import android.content.Intent;
import android.net.ConnectivityManager;
import android.support.v4.view.MenuItemCompat;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.SearchView;
import android.support.v7.widget.Toolbar;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import android.net.NetworkInfo;
import android.app.AlertDialog;
import android.content.DialogInterface;

import com.bitsemart.VisorVideojuego.EditorVideojuegoAdmin;
import com.bitsemart.VisorVideojuego.VisorVideojuegoCliente;
import com.bitsemart.dialogos.IFilterDialogFragment;
import com.bitsemart.dialogos.ISortDialogFragment;
import com.bitsemart.dialogos.InputTextDialogFragment;
import com.bitsemart.dialogos.AskDialogFragment;
import com.bitsemart.dialogos.FilterDialogFragment;
import com.bitsemart.dialogos.SortDialogFragment;
import com.getbase.floatingactionbutton.FloatingActionButton;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.concurrent.ExecutionException;

public class MainActivity extends ActionBarActivity implements ISortDialogFragment, IFilterDialogFragment{

    private BDLocal bdlocal;
    private Toolbar toolbar;
    private static BDHendrix bdhendrix;
    private SearchView searchView;
    private ArrayList<Videojuego> activeList;
    private ArrayList<Videojuego> list;
    private RecyclerView mRecyclerView;
    private RecyclerView.Adapter mAdapter;
    private RecyclerView.LayoutManager mLayoutManager;
    private static FloatingActionButton mFloatingActionButton;
    private static FloatingActionButton mAddGame;
    private static MenuItem adminButton;
    private static boolean admin_mode = false;
    private static String admin_pass = "apu";
    private static AlertDialog dialog;
    private static AlertDialog.Builder builder;
    private Button removeFilters;

    private boolean searching = false;
    private boolean filtering = false;
    private String searchQuery;
    private String devFilter;
    private String genreFilter;

    //Fragments
    FilterDialogFragment mFilterDialogFragment = new FilterDialogFragment();

    public static BDHendrix getBDHendrix() {
        return bdhendrix;
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {

        //SETUP LAYOUT
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        //SETUP ACTION BARmAdapter
        toolbar = (Toolbar) findViewById(R.id.activity_my_toolbar);
        toolbar.setTitle("Bits-e-Mart");
        setSupportActionBar(toolbar);

        //SETUP BDHENDRIX
        try {
            InputStream in = getAssets().open("properties.oracle");
            BufferedReader reader = new BufferedReader(new InputStreamReader(in));
            bdhendrix = new BDHendrix(reader.readLine(), reader.readLine(), this);
        } catch (IOException e) {
            e.printStackTrace();
        }

        //SETUP RECYCLER VIEW
        try {
            //DEBUG
//            activeList = new ArrayList<Videojuego>();
//            for (int i = 0; i<10; i++) {
//                activeList.add(new Videojuego("Videojuego" + i, 2015, 60, "Shooter", "EASOFT"+i, "Descripcion" + i,null));
//            }




            /*ArrayList<String> arr = new ArrayList<String>();
            for (int i=0; i<60; i++) arr.add("Item "+i);*/
            //FIN DEBUG
            //RECYCLERVIEW
            mRecyclerView = (RecyclerView) findViewById(R.id.my_recycler_view);
            mLayoutManager = new LinearLayoutManager(this);
            mRecyclerView.setHasFixedSize(true);
            mRecyclerView.setLayoutManager(mLayoutManager);
            //mAdapter = new VideojuegoAdapter(activeList, R.layout.row);
           updateList(true);


            mRecyclerView.addOnItemTouchListener(
                    new RecyclerItemClickListener(this, new RecyclerItemClickListener.OnItemClickListener() {
                        @Override
                        public void onItemClick(View view, int position) {
                            if (admin_mode) editarJuego(position);
                            else verJuego(position);
                        }
                    })
            );
        } catch (Exception e) {
            e.printStackTrace();
        }
        //FLOATING ACCTION BUTTON
        mFloatingActionButton = (FloatingActionButton) findViewById(R.id.car_icon);
        mFloatingActionButton.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                goToListaCarrito();
            }
        });
        mAddGame = (FloatingActionButton) findViewById(R.id.addGame);
        mAddGame.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                crearJuego();
        }
        });
        if (admin_mode) {
            mFloatingActionButton.setVisibility(View.INVISIBLE);
            mAddGame.setVisibility(View.VISIBLE);
        } else {
            mFloatingActionButton.setVisibility(View.VISIBLE);
            mAddGame.setVisibility(View.INVISIBLE);
        }

        //REMOVE FILTERS
        removeFilters = (Button) findViewById(R.id.limpiar_filtros);
//        removeFilters.setVisibility(View.GONE);
        removeFilters.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                removeFilters.setVisibility(View.GONE);
                devFilter = null;
                genreFilter = null;
                filtering = false;
                try {
                    updateList(false);
                } catch (ExecutionException e) {
                    e.printStackTrace();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });

            //ACCEDER A BDLOCAL
        bdlocal = new BDLocal(this);
        bdlocal.open();
        //bdlocal.addVideojuego(15);
        //ArrayList<Integer> juegos = bdlocal.fetchAllVideojuegos();
        //bdlocal.deleteVideojuego(15);
        //bdlocal.close();
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_main, menu);

        //Modify SearchView
        SearchManager manager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
        MenuItem menuItem = menu.findItem(R.id.action_search);
        searchView = (SearchView) MenuItemCompat.getActionView(menuItem);
        searchView.setQueryHint(getString(R.string.hint_search));
        searchView.setIconifiedByDefault(true);
        searchView.setSearchableInfo(manager.getSearchableInfo(getComponentName()));

        searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
            @Override
            public boolean onQueryTextSubmit(String query) {
                if (query != null) {

                    searchQuery = query;
                    searching = true;
                    try {
                        updateList(false);
                    } catch (ExecutionException e) {
                        e.printStackTrace();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                return true;
            }

            @Override
            public boolean onQueryTextChange(String query) {
                if (query.length() == 0) {
                    searching = false;
                    searchQuery = null;
                    try {
                        updateList(false);
                    } catch (ExecutionException e) {
                        e.printStackTrace();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                return false;
            }

        });

        adminButton = menu.findItem(R.id.action_admin);
        if (admin_mode) adminButton.setTitle("Modo usuario");
        else adminButton.setTitle("Modo admin.");
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_search) {
            return true;
        } else if (id == R.id.action_refresh) {
            try {
                updateList(true);
            } catch (ExecutionException e) {
                e.printStackTrace();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        } else if (id == R.id.action_admin) {
            if (admin_mode){
                admin_mode = false;
                mFloatingActionButton.setVisibility(View.VISIBLE);
                mAddGame.setVisibility(View.INVISIBLE);
                adminButton.setTitle("Modo admin.");
                mostrarMensaje(this, "Has salido del modo administrador");
            } else {
                DialogFragment newFragment = new InputTextDialogFragment();
                Bundle args = new Bundle();
                args.putInt("TYPE", InputTextDialogFragment.TYPE_ADMIN_MODE);
                newFragment.setArguments(args);
                newFragment.show(getFragmentManager(), "Modo administrador");
            }
            return true;
        } else if (id == R.id.action_filter) {
            mFilterDialogFragment.show(getFragmentManager(), "Filtros");
            return true;
            /*fragmentFiltrarRes = new FilterDialogFragment();
            fragmentFiltrarRes.show(getFragmentManager(), "Filtrar Resultados");*/
        } else if (id == R.id.action_sort) {
            DialogFragment newFragment = new SortDialogFragment();
            newFragment.show(getFragmentManager(), "Ordenar Resultados");
        }
        return super.onOptionsItemSelected(item);
    }

    @Override
    public boolean onContextItemSelected(MenuItem item) {
        switch(item.getItemId()) {
            case 0: //FIXME
                AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) item.getMenuInfo();
                DialogFragment newFragment = new AskDialogFragment();
                int position = ((VideojuegoAdapter) mAdapter).getPositionBorrar();
                Bundle args = new Bundle();
                args.putInt("TYPE", AskDialogFragment.TYPE_DELETE_GAME);
                args.putInt("ID", activeList.get(position).getId());
                args.putString("TITLE", activeList.get(position).getTitulo());
                newFragment.setArguments(args);
                newFragment.show(getFragmentManager(), "Borrar juego");
        }
        return super.onContextItemSelected(item);
    }

    private void verJuego(int pos) {
        Videojuego seleccionado = activeList.get(pos);
        Intent i = new Intent(this, VisorVideojuegoCliente.class);
        i.putExtra("ID", seleccionado.getId());
        i.putExtra("TITULO", seleccionado.getTitulo());
        i.putExtra("DESARROLLADOR", seleccionado.getDesarrollador());
        i.putExtra("DESCRIPCION", seleccionado.getDescripcion());
        i.putExtra("GENERO", seleccionado.getGenero());
        i.putExtra("NUM_DESCARGAS", seleccionado.getNumDescargas());
        i.putExtra("PRECIO", seleccionado.getPrecio());
        i.putExtra("YEAR", seleccionado.getYear());
        i.putExtra("IMAGE", seleccionado.getImagen());
        startActivityForResult(i, 0);
    }

    private void editarJuego(int pos) {
        Videojuego seleccionado = activeList.get(pos);
        Intent i = new Intent(this, EditorVideojuegoAdmin.class);
        i.putExtra("ID", seleccionado.getId());
        i.putExtra("TITULO", seleccionado.getTitulo());
        i.putExtra("DESARROLLADOR", seleccionado.getDesarrollador());
        i.putExtra("DESCRIPCION", seleccionado.getDescripcion());
        i.putExtra("GENERO", seleccionado.getGenero());
        i.putExtra("NUM_DESCARGAS", seleccionado.getNumDescargas());
        i.putExtra("PRECIO", seleccionado.getPrecio());
        i.putExtra("YEAR", seleccionado.getYear());
        i.putExtra("IMAGE", seleccionado.getImagen());
        startActivity(i);
    }

    private void crearJuego() {
        Intent i = new Intent(this, EditorVideojuegoAdmin.class);
        i.putExtra("ID", -1);
        i.putExtra("TITULO", "");
        i.putExtra("DESARROLLADOR", "");
        i.putExtra("DESCRIPCION", "");
        i.putExtra("GENERO", "");
        i.putExtra("PRECIO", 0);
        i.putExtra("YEAR", 0);
        startActivity(i);
    }

    private void goToListaCarrito() {
        Intent i = new Intent(this, ListaCarrito.class);
        startActivity(i);
    }

    public static void mostrarMensaje(Context context, String msj) {
        Toast t = Toast.makeText(context, msj, Toast.LENGTH_SHORT);
        t.show();
    }

    public static boolean entrarModoAdministrador(String input_pass) {
        if (comparePass(input_pass)) {
            admin_mode = true;
            mFloatingActionButton.setVisibility(View.INVISIBLE);
            mAddGame.setVisibility(View.VISIBLE);
            adminButton.setTitle("Modo usuario");
            return true;
        }
        return false;
    }

    public static boolean comparePass(String input_pass) {
        return (input_pass.compareTo(admin_pass)==0);
    }

    public static boolean getAdminMode() {
        return admin_mode;
    }

    @Override
    public void onDialogPositiveClick(DialogFragment dialog) {
        //Sacamos los textos
        LayoutInflater inflater = LayoutInflater.from(this);
        View view = inflater.inflate(R.layout.filter_dialog, null);
        EditText editTextDev = (EditText) view.findViewById(R.id.developer_filter);
        EditText editTextGen = (EditText) view.findViewById(R.id.genre_filter);
        //TODO en teoria este comentario deberia funcionar o algo parecido
        /*String developerFilter = editTextDev.getText().toString();
        String genreFilter = editTextGen.getText().toString();*/
        String developerFilter = FilterDialogFragment.developerFilter;
        String genreFilter = FilterDialogFragment.genreFilter;

        //TODO PORT
        if(developerFilter.length() != 0 || genreFilter.length() != 0){
            this.devFilter = developerFilter;
            this.genreFilter = genreFilter;
            filtering = true;
//            Toast.makeText(getBaseContext(), devFilter + " - " + genreFilter, Toast.LENGTH_SHORT).show();


            try {
                updateList(false);
            } catch (ExecutionException e) {
                e.printStackTrace();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            removeFilters.setVisibility(View.VISIBLE);
        }else{
            this.devFilter = null;
            this.genreFilter = null;
            filtering = false;
            try {
                updateList(false);
            } catch (ExecutionException e) {
                e.printStackTrace();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            removeFilters.setVisibility(View.GONE);
        }


    }

    @Override
    public void onDialogNegativeClick(DialogFragment dialog) {
        return;
    }


    public void updateList(boolean remoteUpdate) throws ExecutionException, InterruptedException {
        if(isNetworkAvailable()) {
            if (remoteUpdate) {
                switch(SortDialogFragment.getSortOption()) {
                    case "Descargas": list = bdhendrix.ordenarPorNumDescargas(); break;
                    case "Precio": list = bdhendrix.ordenarPorPrecio(); break;
                    case "Año de lanzamiento": list = bdhendrix.ordenarPorYear();
                    case "Nombre": //FALLTHROUGH
                    default: list = bdhendrix.ordenarPorTitulo(); break;
                }
            }

            if (searching || filtering) {
                ArrayList<Videojuego> localProcessing;
                if (searching) {
                    localProcessing = new ArrayList<>();
                    for (Videojuego vj : list) {
                        if (vj.getTitulo().toLowerCase().contains(searchQuery.toLowerCase())) {
                            localProcessing.add(vj);
                        }
                    }
                } else {
                    localProcessing = list;
                }
                if (filtering) {
                    //Toast.makeText(getBaseContext(), devFilter + " - " + genreFilter, Toast.LENGTH_SHORT).show();
                    ArrayList<Videojuego> aux = new ArrayList<>();
                    //preparamos la lista con flitros
                    if(devFilter.length()!=0 && genreFilter.length()!=0){
                        for(Videojuego v: localProcessing){
                            if(v.getDesarrollador().toLowerCase().contains(devFilter.toLowerCase())
                                    && v.getGenero().toLowerCase().contains(genreFilter.toLowerCase())){
                                aux.add(v);
                            }
                        }
                    }
                    else if(devFilter.length()!=0){
                        for(Videojuego v: localProcessing){
                            if(v.getDesarrollador().toLowerCase().contains(devFilter.toLowerCase())){
                                aux.add(v);
                            }
                        }
                    }
                    else if(genreFilter.length()!=0){
                        for(Videojuego v: localProcessing){
                            if(v.getGenero().toLowerCase().contains(genreFilter.toLowerCase())){
                                aux.add(v);
                            }
                        }
                    }
                    //ponemos la lista filtrada
                    localProcessing = aux;
                }
                activeList = localProcessing;
            } else {
                activeList = list;
            }
            mAdapter = new VideojuegoAdapter(activeList);
            mRecyclerView.setAdapter(mAdapter);

        }
        else {
            builder = new AlertDialog.Builder(this);
            builder.setTitle("Conexión no disponible");
            builder.setMessage("No dispone de conexión a internet.\nNetwork Unavailable!");
            builder.setPositiveButton("Reintentar", new DialogInterface.OnClickListener() {

                @Override
                public void onClick(DialogInterface dialog, int which)
                {
                    dialog.dismiss();
                    try {
                        updateList(true);
                    } catch (ExecutionException e) {
                        e.printStackTrace();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            });
            dialog = builder.create();
            dialog.setCanceledOnTouchOutside(false);
            dialog.show();
        }
    }

    private boolean isNetworkAvailable() {
        ConnectivityManager connectivityManager
                = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo();
        return activeNetworkInfo != null && activeNetworkInfo.isConnected();
    }


    @Override
    public void onSortCriteriaChange(DialogFragment dialog) {
//        Toast.makeText(this, "Cargando...", Toast.LENGTH_LONG).show();
        try{
            updateList(true);
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
    }
}
